'use client'

import React from 'react'
import { Button, Result, Alert, Spin } from 'antd'
import { ReloadOutlined, WifiOutlined, ExclamationCircleOutlined } from '@ant-design/icons'
import { errorHandler, ErrorType, ErrorSeverity } from '@/lib/errorHandler'
import { withRetry, RetryConfigs } from '@/lib/retryMechanism'

interface ApiErrorBoundaryState {
    hasError: boolean
    error: Error | null
    isRetrying: boolean
    retryCount: number
}

interface ApiErrorBoundaryProps {
    children: React.ReactNode
    onRetry?: () => Promise<void>
    maxRetries?: number
    showRetryButton?: boolean
}

export class ApiErrorBoundary extends React.Component<
    ApiErrorBoundaryProps,
    ApiErrorBoundaryState
> {
    private maxRetries: number

    constructor(props: ApiErrorBoundaryProps) {
        super(props)
        this.maxRetries = props.maxRetries || 3
        this.state = {
            hasError: false,
            error: null,
            isRetrying: false,
            retryCount: 0
        }
    }

    static getDerivedStateFromError(error: Error): Partial<ApiErrorBoundaryState> {
        return { hasError: true, error }
    }

    componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
        this.setState({ error })

        // 判断是否为API错误
        const isApiError = this.isApiError(error)

        errorHandler.handleError(error, {
            type: isApiError ? ErrorType.NETWORK_ERROR : ErrorType.UNKNOWN_ERROR,
            severity: isApiError ? ErrorSeverity.MEDIUM : ErrorSeverity.HIGH,
            context: {
                componentStack: errorInfo.componentStack,
                isApiError,
                retryCount: this.state.retryCount
            },
            showNotification: false
        })
    }

    private isApiError(error: Error): boolean {
        const message = error.message.toLowerCase()
        return message.includes('fetch') ||
            message.includes('network') ||
            message.includes('api') ||
            message.includes('request') ||
            message.includes('response') ||
            message.includes('timeout')
    }

    handleRetry = async () => {
        if (this.state.retryCount >= this.maxRetries) {
            return
        }

        this.setState({ isRetrying: true })

        try {
            if (this.props.onRetry) {
                await withRetry(this.props.onRetry, RetryConfigs.API_CALL)
            }

            // 重试成功，重置状态
            this.setState({
                hasError: false,
                error: null,
                isRetrying: false,
                retryCount: 0
            })
        } catch (retryError) {
            // 重试失败
            this.setState(prevState => ({
                isRetrying: false,
                retryCount: prevState.retryCount + 1,
                error: retryError instanceof Error ? retryError : prevState.error
            }))

            errorHandler.handleError(retryError, {
                type: ErrorType.NETWORK_ERROR,
                severity: ErrorSeverity.HIGH,
                context: {
                    retryAttempt: this.state.retryCount + 1,
                    maxRetries: this.maxRetries
                }
            })
        }
    }

    handleRefresh = () => {
        window.location.reload()
    }

    getErrorType(): 'network' | 'server' | 'client' | 'unknown' {
        if (!this.state.error) return 'unknown'

        const message = this.state.error.message.toLowerCase()

        if (message.includes('network') || message.includes('fetch') || message.includes('connection')) {
            return 'network'
        }
        if (message.includes('server') || message.includes('500') || message.includes('503')) {
            return 'server'
        }
        if (message.includes('400') || message.includes('401') || message.includes('403') || message.includes('404')) {
            return 'client'
        }

        return 'unknown'
    }

    getErrorMessage(): { title: string; description: string; suggestions: string[] } {
        const errorType = this.getErrorType()

        switch (errorType) {
            case 'network':
                return {
                    title: '网络连接错误',
                    description: '无法连接到服务器，请检查您的网络连接。',
                    suggestions: [
                        '检查网络连接是否正常',
                        '确认防火墙设置允许访问',
                        '尝试刷新页面',
                        '稍后重试'
                    ]
                }
            case 'server':
                return {
                    title: '服务器错误',
                    description: '服务器暂时无法处理请求，请稍后重试。',
                    suggestions: [
                        '服务器可能正在维护',
                        '稍后重试',
                        '联系技术支持'
                    ]
                }
            case 'client':
                return {
                    title: '请求错误',
                    description: '请求参数有误或权限不足。',
                    suggestions: [
                        '检查输入参数',
                        '确认操作权限',
                        '重新登录',
                        '联系管理员'
                    ]
                }
            default:
                return {
                    title: 'API调用错误',
                    description: '系统出现未知错误，请稍后重试。',
                    suggestions: [
                        '刷新页面重试',
                        '清除浏览器缓存',
                        '联系技术支持'
                    ]
                }
        }
    }

    render() {
        if (this.state.hasError) {
            const { title, description, suggestions } = this.getErrorMessage()
            const canRetry = this.state.retryCount < this.maxRetries && this.props.showRetryButton !== false
            const errorType = this.getErrorType()

            if (this.state.isRetrying) {
                return (
                    <div className="api-error-boundary h-full flex items-center justify-center">
                        <div className="text-center">
                            <Spin size="large" />
                            <div className="mt-4 text-gray-600">正在重试...</div>
                        </div>
                    </div>
                )
            }

            return (
                <div className="api-error-boundary h-full flex items-center justify-center bg-gray-50">
                    <div className="max-w-md w-full p-6">
                        <Result
                            status={errorType === 'network' ? 'error' : 'warning'}
                            title={title}
                            subTitle={description}
                            icon={errorType === 'network' ? <WifiOutlined /> : <ExclamationCircleOutlined />}
                            extra={[
                                canRetry && (
                                    <Button
                                        type="primary"
                                        key="retry"
                                        icon={<ReloadOutlined />}
                                        onClick={this.handleRetry}
                                        loading={this.state.isRetrying}
                                    >
                                        重试 ({this.maxRetries - this.state.retryCount} 次剩余)
                                    </Button>
                                ),
                                <Button
                                    key="refresh"
                                    onClick={this.handleRefresh}
                                >
                                    刷新页面
                                </Button>
                            ].filter(Boolean)}
                        />

                        {/* 错误详情 */}
                        {this.state.error && (
                            <Alert
                                message="错误信息"
                                description={this.state.error.message}
                                type="error"
                                showIcon
                                className="mt-4"
                            />
                        )}

                        {/* 解决建议 */}
                        <div className="mt-4 p-4 bg-blue-50 border border-blue-200 rounded">
                            <h4 className="font-medium text-blue-800 mb-2">解决建议:</h4>
                            <ul className="text-sm text-blue-700 space-y-1">
                                {suggestions.map((suggestion, index) => (
                                    <li key={index}>• {suggestion}</li>
                                ))}
                            </ul>
                        </div>

                        {/* 重试信息 */}
                        {this.state.retryCount > 0 && (
                            <div className="mt-4 p-3 bg-yellow-50 border border-yellow-200 rounded">
                                <div className="text-sm text-yellow-800">
                                    已重试 {this.state.retryCount} 次，剩余 {this.maxRetries - this.state.retryCount} 次机会
                                </div>
                            </div>
                        )}

                        {/* 开发环境调试信息 */}
                        {process.env.NODE_ENV === 'development' && this.state.error && (
                            <details className="mt-4 p-4 bg-red-50 border border-red-200 rounded">
                                <summary className="cursor-pointer font-medium text-red-800">
                                    开发调试信息 (点击展开)
                                </summary>
                                <div className="mt-2 text-sm">
                                    <div className="mb-2">
                                        <strong>错误类型:</strong> {errorType}
                                    </div>
                                    <div className="mb-2">
                                        <strong>错误消息:</strong> {this.state.error.message}
                                    </div>
                                    <div className="mb-2">
                                        <strong>错误堆栈:</strong>
                                        <pre className="mt-1 text-red-600 text-xs whitespace-pre-wrap overflow-auto max-h-32">
                                            {this.state.error.stack}
                                        </pre>
                                    </div>
                                </div>
                            </details>
                        )}
                    </div>
                </div>
            )
        }

        return this.props.children
    }
}

export default ApiErrorBoundary